﻿using System;
using System.Linq;
using C = KC.Overhead.Constants;
using KC.ExtensionMethods;
using DAL = KC.DataAccess;
using Logger = KC.Logging.Logger;

namespace KC.Business.Net.Tracking
{
	public class Spiders
	{
		/// <summary>Detects if a request came from a spider</summary>
		/// <param name="UserAgent">(Optional) User agent, if available</param>
		/// <param name="IP">IP Address of requestor</param>
		/// <returns>is this a spider?</returns>
		public static bool isSpider(string UserAgent, string IP)
		{
			if (string.IsNullOrEmpty(IP)) throw new ArgumentNullException("IP", "Unable to detect spider, this is an invalid Request with no IP address");
			try { 
			foreach (string UserAgent2 in DAL.Net.Tracking.Spiders.GetSpiderUserAgents()) {
				if (string.IsNullOrEmpty(UserAgent2)) continue;
				if (!string.IsNullOrEmpty(UserAgent) && UserAgent.ToLower().Contains(UserAgent2.ToLower().Trim())) return true;
				if (IP.Trim().StartsWith(UserAgent2)) return true; }
			}
			catch {}
			return false;
		}

		/// <summary>Did this referral come from a search engine click?</summary>
		/// <param name="Referrer">Referrer string from Request object</param>
		/// <param name="Engine">Search Engine from whence the click came</param>
		/// <param name="Query">What the user Googled for</param>
		/// <returns>Was this a search engine referral?</returns>
		public static bool TryParseSpiderReferral(Uri Referrer, out string Engine, out string Query)
		{
			Engine = null;
			Query = null;


			if (Referrer == null || string.IsNullOrEmpty(Referrer.AbsoluteUri)) return false;
			string referrer = Referrer.AbsoluteUri.Replace("/#", "/?");
			if (!referrer.Contains('?')) return false;

			referrer = referrer.Replace(";", "") // Yahoo can suck a donkey; this shit ain't valid
				.Replace("?", "?" + DateTime.Now.Ticks.ToString() + "&"); // ParseQueryString loses on [0]
			
			System.Collections.Specialized.NameValueCollection QueryString = System.Web.HttpUtility.ParseQueryString(referrer.Substring(referrer.IndexOf('?')));
			Engine = Referrer.GetRootDomain().ToLower();

			string QueryMember = GetQueryMember(Engine); // Part of the QueryString that means "Search query" to a given Search Engine
			if (string.IsNullOrEmpty(QueryMember) || string.IsNullOrEmpty(QueryString[QueryMember])) throw new ArgumentOutOfRangeException("QueryMember");
			if (Engine.Contains('.')) Engine = Engine.Substring(0, Engine.IndexOf('.'));

			Query = System.Web.HttpUtility.UrlDecode(QueryString[QueryMember].Trim());
			return !string.IsNullOrEmpty(Query);
		}

		/// <summary>Gets the QueryString key that represents the Search Query</summary>
		/// <param name="Engine">What search engine is this?</param>
		/// <returns>QueryString key name of the search query</returns>
		protected static string GetQueryMember(string Engine)
		{
			if (string.IsNullOrEmpty(Engine)) throw new ArgumentNullException("Engine");
			switch (Engine)
			{
				case "google.com":
				case "live.com":
				case "msn.com":
				case "altavista.com":
				case "search.com":
				case "ask.com":
				case "cuil.com":
				case "bing.com":
					return  "q";
				case "yahoo.com":
					return  "p";
				case "lycos.com":
				case "business.com":
				case "aol.com":
				case "netscape.com":
				case "clusty.com":
					return  "query";
				case "baidu.com":
					return  "wd";
			}
			throw new ArgumentOutOfRangeException("Engine", "Cannot identify QueryMember for unknown Engine");
		}
	}
}
